Here we use Phea to
compute the overt disseminated intravascular coagulation score produced
by the International Society for Thrombosis and Hemostasis:
For this vignette, we will assume you have a SQL server at
localhost, with patient data in OMOP Common Data Model v5.4
format, inside schema cdm_new_york3.
This vignette was produced using synthetic data generated by Synthea Patient Generator and ETL’d into OMOP CDM v5.4 by ETL-Synthea. Lots of thanks to both projects!
First we connect to the server. Calling setup_phea() is
optional, but it enables the convenience functions slqt()
and sql0().
library(phea)
suppressPackageStartupMessages(library(dplyr))
# Connect to SQL server.
dbcon <- DBI::dbConnect(
RPostgres::Postgres(),
host = 'localhost', port = 7654, dbname = 'fort',
user = cred$pg$user, password = cred$pg$pass)
# Provide the connection to Phea so we can use the sqlt() and sql0() shorthands.
setup_phea(dbcon, 'cdm_new_york3')
Let component d_dimer be records from table
MEASUREMENT where measurement_concept_id is
equal to 3051714.
# LOINC code 48065-7 Fibrin D-dimer FEU [Mass/volume] in Platelet poor plasma
# OMOP CDM concept ID 3051714
d_dimer <- sqlt(measurement) |>
filter(measurement_concept_id == 3051714) |>
make_component(
.pid = person_id,
.ts = measurement_datetime)
Let component inr be records from table
MEASUREMENT where measurement_concept_id is
equal to 3022217.
# LOINC code 6301-6 INR in Platelet poor plasma by Coagulation assay
# OMOP CDM concept ID 3022217
inr <- sqlt(measurement) |>
filter(measurement_concept_id == 3022217) |>
make_component(
.pid = person_id,
.ts = measurement_datetime)
Let component platelet be records from table
MEASUREMENT where measurement_concept_id is
equal to 3024929.
# LOINC code 777-3 Platelets [#/volume] in Blood by Automated count
# OMOP CDM concept ID 3024929
platelet <- sqlt(measurement) |>
filter(measurement_concept_id == 3024929) |>
make_component(
.pid = person_id,
.ts = measurement_datetime)
The phenotype logic can be regarded as having two steps:
is platelet count under 50,000?yes there is overt DIC or
no there is no overt DIC.We will accomplish that using a sequence of formulas.
dic_score <- calculate_formula(
components = list(
d_dimer = d_dimer,
inr = inr,
platelet = platelet),
fml = list(
d_dimer_points = 'case
when d_dimer_value_as_number >= 4 then 3
when d_dimer_value_as_number >= 0.4 then 2
when d_dimer_value_as_number < 0.4 then 0
else null end',
inr_points = 'case
when inr_value_as_number <= 1.2 then 0
when inr_value_as_number <= 1.7 then 1
when inr_value_as_number > 1.7 then 2
else null end',
platelet_points = 'case
when platelet_value_as_number < 50 then 2
when platelet_value_as_number <= 100 then 1
when platelet_value_as_number > 100 then 0
else 0 end',
isth_score = 'd_dimer_points + inr_points + platelet_points',
overt_dic = 'case when isth_score >= 5 then 1 else 0 end'),
window = '2 days')
if(!exists('pids'))
pids <- dic_score |>
select(pid) |>
distinct() |>
pull()
phea_plot(dic_score, sample(pids, 1))
#> Collecting lazy table, done. (turn this message off with `verbose = FALSE`)
#> Warning in min(chart_data$value, na.rm = TRUE): no non-missing arguments to min; returning Inf
#> Warning in max(chart_data$value, na.rm = TRUE): no non-missing arguments to max; returning -Inf
#> Warning in min(chart_data$value, na.rm = TRUE): no non-missing arguments to min; returning Inf
#> Warning in max(chart_data$value, na.rm = TRUE): no non-missing arguments to max; returning -Inf
#> Warning in min(chart_data$value, na.rm = TRUE): no non-missing arguments to min; returning Inf
#> Warning in max(chart_data$value, na.rm = TRUE): no non-missing arguments to max; returning -Inf
#> Warning in min(chart_data$value, na.rm = TRUE): no non-missing arguments to min; returning Inf
#> Warning in max(chart_data$value, na.rm = TRUE): no non-missing arguments to max; returning -Inf
#> Warning in min(chart_data$value, na.rm = TRUE): no non-missing arguments to min; returning Inf
#> Warning in max(chart_data$value, na.rm = TRUE): no non-missing arguments to max; returning -Inf